<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<!--
    	作者：zyl
    	时间：2017-05-27
    	描述：路径方向与非零环绕原则

    	如果绘图路径是循环的，或是包含多个相交的子路径，那么canvas的绘图环境变量就必须要判断，当fill()方法被调用时，应该如何对当前路径进行填充。
	    canvas在填充那种互相有交叉路径时就会使用到“非零环绕规则”。“非零环绕规则是这么来判断自我交叉情况的路径的：对于路径中的任意给定的区域，从该区域内部画一条足够长的线段，使此线段的终点完全落在路径范围之外。
	
		　接下来，将计数器初始化为0，然后，每当这条线段与路径上的直线或曲线相交时，就改变计数器的值。
		（这里是重点）如果是与路径的顺时针部分相交，则加1，如果是与路径的逆时针部分相交，则减1.若计数器的值最终不为0，那么此区域就在路径里面（这里理解了就好说了），
		在调用fill()方法时，浏览器就会对其进行填充。如果最终值是0，那么此区域就不在路径内部，浏览器也就不会对其进行填充了。
    -->
	<body>
			<canvas id="canvas" style="border: 2px solid #ccc; display: block;margin: 50px auto;">
			
		</canvas>
	</body>
	<script>
	window.onload = function(){   
        var canvas = document.getElementById("canvas");   
        canvas.width = 800;   
        canvas.height = 600;   
        var context = canvas.getContext("2d");   
        context.fillStyle = "#FFF";   
        context.fillRect(0,0,800,600);   
  
        context.beginPath();   
        context.rect(200,100,400,400);   
        drawPathRect(context, 250, 150, 300, 150);   
        drawPathTriangle(context, 345, 350, 420, 450, 270, 450);   
        context.arc(500, 400, 50, 0, Math.PI * 2, true);  
        context.closePath();   
  
        context.fillStyle = "#058";   
        context.shadowColor = "gray";   
        context.shadowOffsetX = 10;   
        context.shadowOffsetY = 10;   
        context.shadowBlur = 10;   
        context.fill();   
  
    };   
  
   //逆时针绘制矩形   
    function drawPathRect(cxt, x, y, w, h){   
        /**  
         * 这里不能使用beginPath和closePath，  
         * 不然就不属于子路径而是另一个全新的路径，  
        * 无法使用非零环绕原则  
         */  
        cxt.moveTo(x, y);   
        cxt.lineTo(x, y + h);   
        cxt.lineTo(x + w, y + h);   
        cxt.lineTo(x + w, y);   
        cxt.lineTo(x, y);   
  
    }   
  
    //逆时针绘制三角形   
    function drawPathTriangle(cxt, x1, y1, x2, y2, x3, y3){   
        cxt.moveTo(x1,y1);   
        cxt.lineTo(x3,y3);   
        cxt.lineTo(x2,y2);   
        cxt.lineTo(x1,y1);   
    }   
  
</script>   

</html>
